"use server";

import { type Prisma, TagTypeEnum } from "@prisma/client";

import { prisma } from "@/lib/prisma";
import { nextPage } from "@/utils";

import {
  type CreateTagDTO,
  type GetTagListDTO,
  type UpdateTagDTO,
  verifyCreateTag,
  verifyGetTagList,
  verifyUpdateTag,
} from "../types";

export const getTagListMapper = async (params: GetTagListDTO) => {
  const result = await verifyGetTagList.safeParseAsync(params);

  if (!result.success) {
    const error = result.error.format()._errors.join(";");
    throw new Error(error);
  }

  const where: Prisma.TagWhereInput = {};

  if (result.data.type) {
    where.type = result.data.type;
  }

  if (result.data.name) {
    where.OR = [
      {
        name: {
          contains: result.data.name.trim(),
        },
      },
    ];
  }

  const [tags, total] = await Promise.all([
    prisma.tag.findMany({
      where,
      include: {
        blogs: true,
        _count: true,
      },
      take: result.data.pageSize,
      skip: nextPage(result.data.pageIndex, result.data.pageSize),
    }),
    prisma.tag.count({ where }),
  ]);

  return { tags, total };
};

export const getTagListByTypeMapper = async (type?: TagTypeEnum) => {
  const cond: Prisma.TagWhereInput = {
    type: {
      in: type ? [TagTypeEnum.ALL, type] : [TagTypeEnum.ALL],
    },
  };

  const tags = await prisma.tag.findMany({
    where: cond,
    orderBy: {
      createdAt: "desc",
    },
  });

  const total = tags.length;

  return { tags, total };
};

export const createTagMapper = async (params: CreateTagDTO) => {
  const { name, type } = await verifyCreateTag.parseAsync(params);

  const existingTag = await prisma.tag.findFirst({
    where: {
      OR: [{ name }],
    },
  });

  if (existingTag) {
    throw new Error("标签名称或者slug重复");
  }

  await prisma.tag.create({
    data: { name, type },
  });
};

export const deleteTagByIDMapper = async (id: string) => {
  const tag = await prisma.tag.findUnique({ where: { id } });
  if (!tag) {
    throw new Error("标签不存在");
  }

  await prisma.tag.delete({
    where: {
      id,
    },
  });
};

export const updateTagMapper = async (params: UpdateTagDTO) => {
  const { id, ...data } = await verifyUpdateTag.parseAsync(params);

  const tag = await prisma.tag.update({
    data,
    where: {
      id,
    },
  });

  if (!tag) {
    throw new Error("标签不存在");
  }
};

export const getTagByIDMapper = async (id: string) => {
  const tag = await prisma.tag.findUnique({ where: { id } });
  return { tag };
};
